#include <51func.h>
int main(int argc, char *argv[])
{
    // ./1_azhen 192.168.118.128 1234
    ARGS_CHECK(argc,3);
    // socket
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    // setsockopt
    int arg = 1; // REUSEADDR的参数值为真
    int ret = setsockopt(sockfd,SOL_SOCKET,
                         SO_REUSEADDR,&arg,sizeof(arg));
    ERROR_CHECK(ret,-1,"setsockopt");
    // bind
    ret = bind(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"bind");
    // listen
    listen(sockfd,10);
    // accept
    struct sockaddr_in clientAddr;
    socklen_t clientAddrLength = sizeof(clientAddr); //必须赋初值
    
    int netfd[1024] = {0};//保存每个客户端建立的netfd
    for(int i = 0; i < 1024; ++i){
        netfd[i] = -1; //netfd[i] 值为 -1 说明netfd无效
    }
    int curidx = 0; //下一个要放入的netfd的下标
    
    char buf[4096];
    fd_set monitorset;
    fd_set readyset;
    FD_ZERO(&monitorset);
    FD_SET(sockfd,&monitorset);
    while(1){
        memcpy(&readyset,&monitorset,sizeof(fd_set));
        select(1024,&readyset,NULL,NULL,NULL);
        if(FD_ISSET(sockfd,&readyset)){
            netfd[curidx] = accept(sockfd,(struct sockaddr *)&clientAddr,&clientAddrLength);
            printf("client ip = %s, port = %d\n",
                           inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
            FD_SET(netfd[curidx],&monitorset);
            ++curidx;
        }
        for(int i = 0; i < curidx; ++i){//遍历所有的netfd
            if(netfd[i] != -1 && FD_ISSET(netfd[i],&readyset)){//某个netfd就绪
                bzero(buf,sizeof(buf));
                ssize_t sret = recv(netfd[i],buf,sizeof(buf),0);//读取出来
                if(sret == 0){ // netfd 断开
                    FD_CLR(netfd[i],&monitorset);
                    close(netfd[i]);
                    netfd[i] = -1;
                    continue;
                }
                for(int j = 0; j < curidx; ++j){
                    if(j == i || netfd[j] == -1){
                        continue;
                    }
                    //转发给了除了自己以及已经断开的所有netfd
                    send(netfd[j],buf,strlen(buf),0);
                }
            }
        }
    }
    return 0;
}

